context("testing basic population/community patterns")


test_that("simple community patterns",{
  data(BCI)
  expect_equal(area(BCI),prod(attr(BCI,"plotdim")))
  expect_equal(plotdim(BCI),attr(BCI,"plotdim"))
  expect_equal(total_abundance(BCI),nrow(BCI))
  expect_equal(total_richness(BCI),length(unique(BCI$species)))
  expect_equal(species_list(BCI),levels(BCI$species)) #species list should be the same order of levels of species
  spab=species_abundance(BCI)
  expect_equal(names(spab),species_list(BCI))
  expect_equal(mean(spab),mean(table(BCI$species)))
  expect_equal(sd(spab),sd(table(BCI$species)))
  expect_equal(median(spab),median(table(BCI$species)))
})

test_that("neighborhood structure",{
  #create a very simple community
  com=community(species=c(1,1,1,1,2),x=c(0,1,1,0,0.5),y=c(0,0,1,1,0.5),plotdim=c(1,1))
  #for the focus point with radiu 0.5
  ni=frnn(com,fx=0.5,fy=0.5,rRange=c(0,0.5),info="both")
  expect_equal(names(ni[[1]]),c("index","dist")) #two type of info
  expect_equal(length(ni[[1]]$index),0) #no point return
  expect_equal(length(ni[[1]]$dist),length(ni[[1]]$index)) #neighter for distance
  
  ni2=frnn(com,fx=0.5,fy=0.5,rRange=c(0,1),info="both")
  expect_equal(names(ni2[[1]]),c("index","dist")) #two type of info
  expect_equal(length(ni2[[1]]$index),4) #expect four individuals
  expect_equal(sort(ni2[[1]]$index),1:4) #expect index
  expect_true(all(ni2[1]$dist==sqrt(2)*0.5)) #expect distance
  
  ni3=frnn(com,fx=0.5,fy=0.5,rRange=c(0,sqrt(2)*0.5)) #should be equal to ni2
  expect_equal(ni3,ni2)
  
  ni4=frnn(com,fx=0,fy=0,rRange=c(0,0.5)) #the point in com should not be included
  expect_equal(length(ni4[[1]]$index),0)
  
  ni5=frnn(com,fx=0,fy=0.001,rRange=c(0,0.5)) #one point should included
  expect_equal(length(ni5[[1]]$index),1)
  
  expect_error(frnn(com,fx=1.1,fy=1.1,rRange=c(0,0.5)),
                 "some focus points located outside of the plot")
})

test_that("mark correlation function",{
  
  #A simplist community
  com=community(species=1:2,x=c(10,11),y=c(10,11),plotdim = c(20,20),traits = data.frame(dbh=1:2))
  com2=community(species=1:3,x=c(10,11,2),y=c(10,11,2),plotdim = c(20,20),traits = data.frame(dbh=1:3))
  
  re_t0=markcorr(com,com,r=seq(0,2,0.1),h=0.1,testfun = "t1",nrep = 0)
  expect_equal(attr(re_t0,"normal_constant"),mean(com$dbh)^2)
  expect_true(all(re_t0$obs[15:16]==prod(com$dbh)/mean(com$dbh)^2)) #only r around 1.414 have values
  expect_true(all(is.nan(re_t0$obs[-c(15:16)]))) #non otherwise
  
  re_t1=markcorr(com,com,r=seq(0,1,0.1),h=2,testfun = "t1",nrep = 0)
  expect_equal(attr(re_t1,"normal_constant"),mean(com$dbh)^2)
  expect_true(all(re_t1$obs==prod(com$dbh)/mean(com$dbh)^2)) 
  
  re_t1=markcorr(com2,com2,r=seq(0,1,0.1),h=2,testfun = "t1",nrep = 0)
  expect_equal(attr(re_t1,"normal_constant"),mean(com2$dbh)^2) #normalized constant will be different
  expect_true(all(re_t1$obs==prod(com2$dbh[-3])/mean(com2$dbh)^2)) #the last (2,2) point have no effect on result
  
  
  re_t2=markcorr(com,com,r=seq(0,1,0.1),h=2,testfun = "t2",nrep=0)
  expect_equal(attr(re_t2,"normal_constant"),mean(com$dbh))
  expect_true(all(re_t2$obs==sum(com$dbh)/2/mean(com$dbh)))
  
  re_t2=markcorr(com2,com2,r=seq(0,1,0.1),h=2,testfun = "t2",nrep=0)
  expect_equal(attr(re_t2,"normal_constant"),mean(com2$dbh)) #normalized constant will be different
  expect_true(all(re_t2$obs==sum(com2$dbh[-3])/2/mean(com2$dbh)))  #the last (2,2) point have no effect on result
  
  re_t6=markcorr(com,com,r=seq(0,1,0.1),h=2,testfun = "t6",nrep=0)
  expect_true(all(re_t6$obs==prod(com$dbh-mean(com$dbh))/attr(re_t6,"normal_constant")))
  
  re_t7=markcorr(com,com,r=seq(0,1,0.1),h=2,testfun = "t7",nrep=0)
  expect_true(all(is.nan(re_t7$obs))) #all equal zero because ki(r)==mean(k(r))
  
  re_t7=markcorr(com2,com2,r=seq(0,1,0.1),h=2,testfun = "t7",nrep=0)
  expect_true(all(re_t7$obs!=0)) #non equal zero because ki(r)!=mean(k(r))
  #for any distance r, it should be all like that
  obs_exp=sum((com2$dbh[-3]-mean(com2$dbh))*(c(1,1)-mean(c(1,1,0))))/2/attr(re_t7,"normal_constant")
  expect_true(all(re_t7$obs==obs_exp))
  
  # #after above tests, it seems the main framework works. let compares it with results from other funciton
  # library(spatstat)
  # com_ppp=com_to_ppp(com)
  # com_ppp$marks=com_ppp$marks[,-1,drop=FALSE]
  # com2_ppp=com_to_ppp(com2)
  # re_ot1=spatstat::markcrosscorr(com_ppp,r=seq(0,1,0.1),kernel="rectangular",bw=2,correction="none",normalise=TRUE)
})